package com.such.kit.io.bean;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.such.kit.io.source.MemoryIOSource;
import com.such.kit.io.template.XmlIOTemplate;
import com.such.kit.validate.ValidateCommons;

/**
 * @author SUCH
 * <pre>
 * xml 模板配置项
 * 由于 {@link MemoryIOSource#inputResult} 所构建数据的特殊性（平面数据）
 * 需要快捷方式将平面数据转换为结构化数据或将结构化数据转换为平面数据
 * </pre>
 */
public class XmlTemplateItemConfig {

	/** TYPE_OBJECT：入参或返回值的类型.对象 */
	public static final String TYPE_OBJECT = "object";
	/** TYPE_ARRAY：入参或返回值的类型.数组 */
	public static final String TYPE_ARRAY = "array";

	/** expression：表达式 [参考 {@link XmlIOTemplate#IO_INPUT_EXPRESSION} | 参考 {@link XmlIOTemplate#IO_OUTPUT_EXPRESSION}] */
	private String expression;
	/**
	 * key：入参或返回值的键（Map 的 key）
	 * <pre>
	 * type = {@link #TYPE_OBJECT} 时 key 可以为空
	 * </pre>
	 */
	private String key;
	/** type：入参或返回值的类型 [默认为 {@link #TYPE_OBJECT}] [{@link #TYPE_OBJECT} | {@link #TYPE_ARRAY}] */
	private String type = TYPE_OBJECT;
	/** subItems：下级子项 */
	private List<XmlTemplateItemConfig> subItemConfigs;
	/** subItemConfigIndexStorer：下级子项索引 */
	private Map<String, Integer> subItemConfigIndexStorer;
	/** converter：将 key 转换为 targetKey */
	private Map<String, String> converter;

	public XmlTemplateItemConfig(String expression) {
		this.expression = expression;
	}

	public XmlTemplateItemConfig(String expression, Map<String, String> converter) {
		this(expression);
		this.converter = converter;
	}

	public XmlTemplateItemConfig(String expression, String key) {
		this(expression);
		this.key = key;
	}

	public XmlTemplateItemConfig(String expression, String key, Map<String, String> converter) {
		this(expression, key);
		this.converter = converter;
	}

	public XmlTemplateItemConfig(String expression, String key, String type) {
		this(expression, key);
		this.type = type;
	}

	public XmlTemplateItemConfig(String expression, String key, String type, Map<String, String> converter) {
		this(expression, key, type);
		this.converter = converter;
	}

	/** [参考 {@link #expression}] */
	public String getExpression() {
		return this.expression;
	}

	/** [参考 {@link #expression}] */
	public void setExpression(String expression) {
		this.expression = expression;
	}

	/** [参考 {@link #key}] */
	public String getKey() {
		return this.key;
	}

	/** [参考 {@link #key}] */
	public void setKey(String key) {
		this.key = key;
	}

	/** [参考 {@link #type}] */
	public String getType() {
		return this.type;
	}

	/** [参考 {@link #type}] */
	public void setType(String type) {
		this.type = type;
	}

	/** [参考 {@link #subItemConfigs}] */
	public List<XmlTemplateItemConfig> getSubItemConfigs() {
		return this.subItemConfigs;
	}

	/** [参考 {@link #subItems}] */
	public void setSubItemConfigs(List<XmlTemplateItemConfig> subItemConfigs) {
		if (ValidateCommons.isNotEmpty(subItemConfigs)) {
			for (XmlTemplateItemConfig subItemConfig : subItemConfigs) {
				addSubItemConfig(subItemConfig);
			}
		}
	}

	/**
	 * <pre>
	 * 添加下级配置子项
	 * </pre>
	 * @param subItemConfig 下级配置子项
	 */
	public void addSubItemConfig(XmlTemplateItemConfig subItemConfig) {
		if (ValidateCommons.isEmpty(this.subItemConfigs)) {
			this.subItemConfigs = new ArrayList<XmlTemplateItemConfig>();
		}
		if (ValidateCommons.isEmpty(this.subItemConfigIndexStorer)) {
			this.subItemConfigIndexStorer = new HashMap<String, Integer>();
		}
		this.subItemConfigIndexStorer.put(subItemConfig.getKey(), this.subItemConfigs.size());
		this.subItemConfigs.add(subItemConfig);
	}

	/**
	 * <pre>
	 * 获取下级配置子项
	 * </pre>
	 * @param key 键
	 * @return 下级配置子项
	 */
	public XmlTemplateItemConfig getSubItemConfig(String key) {
		XmlTemplateItemConfig subItemConfig = null;
		if (ValidateCommons.isNotEmpty(this.subItemConfigIndexStorer)) {
			Integer index = this.subItemConfigIndexStorer.get(key);
			if (ValidateCommons.isNotEmpty(index)) {
				subItemConfig = this.subItemConfigs.get(index);
			}
		}
		return subItemConfig;
	}

	/** [参考 {@link #converter}] */
	public Map<String, String> getConverter() {
		return this.converter;
	}

	/** [参考 {@link #converter}] */
	public void setConverter(Map<String, String> converter) {
		this.converter = converter;
	}

	/**
	 * <pre>
	 * 填充转换器
	 * </pre>
	 * @param key 键
	 * @param targetKey 目标键
	 */
	public void addConverter(String key, String targetKey) {
		if (ValidateCommons.isEmpty(this.converter)) {
			this.converter = new HashMap<String, String>();
		}
		this.converter.put(key, targetKey);
	}

	/**
	 * <pre>
	 * 将 key 转换为 targetKey
	 * </pre>
	 * @param key 键
	 * @return 目标键
	 */
	public String convert(String key) {
		String targetKey = null;
		if (ValidateCommons.isNotEmpty(this.converter)) {
			targetKey = this.converter.get(key);
		}
		if (ValidateCommons.isEmpty(targetKey)) {
			targetKey = key;
		}
		return targetKey;
	}

}
